<?php
/**
 * Created by PhpStorm.
 * User: linhongzhao
 * Date: 18-5-12
 * Time: 下午2:48
 */

namespace EFrame;

use Psr\Cache\CacheItemInterface;

class CacheItem implements CacheItemInterface
{
    private $key;
    private $value;
    private $expires = 0;// 过期时间，时间戳形式

    /**
     * @var bool 当前value是否被序列化存储
     */
    private $is_packed = false;

        /**
     * @var int 创建时间,仅__construct中赋值
     */
    private $createTime;
    /**
     * @var int 命中次数
     */
    private $chit = 1;

    /**
     * CacheItem constructor.
     * @param string $key
     */
    public function __construct($key)
    {
        $this->key = $key;
        $this->createTime = time();
    }

    /**
     * @return string
     */
    public function getKey()
    {
        return $this->key;
    }

    /**
     * @return mixed|null
     */
    public function get()
    {
        if ($this->isHit()) {
            $this->chit++;// 命中次数+1
//            return $this->is_packed ? $this->unpack() : $this->value;
            return $this->value;
        }
        return null;
    }

    public function isHit()
    {
        if ($this->expires === 0 || time()+1 < $this->expires) {// +1秒以适应可能存在的延迟
            return true;
        }
        return false;
    }

    /**
     * 赋值后将导致过期时间复位，需要重新限定时间
     * @param mixed $value
     * @return void|static
//     * @throws InvalidArgument Resource types cannot be stored
     */
    public function set($value)
    {
        if (is_string($value) || is_int($value)) {
            $this->value = $value;
            $this->expires = 0;
        } elseif (is_string($value)) {
//            $this->value = self::pack($value);
            $this->is_packed = true;
        }
    }

    /**
     * @param \DateTimeInterface $expiration
     * @return void|static
     */
    public function expiresAt($expiration)
    {
        $this->expires = $expiration;
    }

    public function expiresAfter($time)
    {
        $this->expires = time() + $time;
    }

//    /**
//     * @param $obj
//     * @return string
//     * @throws ArgumentException Resource types cannot be stored
//     */
//    private static function pack($obj)
//    {
//        if (is_resource($obj)) {
//            throw new ArgumentException('Resource types cannot be stored!');
//        }
//        return serialize($obj);
//    }
//
//    /**
//     * 返回当前值的解序列化
//     * @return mixed
//     */
//    private function unpack()
//    {
//        return unserialize($this->value);
//    }

    public function __clone()
    {
        if (is_object($this->value)) {
            // The value will be cloned if it is object
            $this->value = clone $this->value;
        }
    }
}